/*
 *
 *  Copyright (C) 2010 GSyC/LibreSoft
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Roberto Calvo Palomino <rocapal@libresoft.es>
 *
 */

package com.LibreGeoSocial.App.AlarmManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.IBinder;
import android.util.Log;

import com.LibreGeoSocial.Api.GeoNode;
import com.LibreGeoSocial.Api.Layers.NodeListLayer;
import com.LibreGeoSocial.App.NodeList;
import com.LibreGeoSocial.App.R;
import com.LibreGeoSocial.App.Routes.ILocationServiceListener;
import com.LibreGeoSocial.App.Routes.LocationService;

public class AlarmService extends Service {

	private static String FILE_ALARMS = "/sdcard/alarms.obj";
	
	private NotificationManager mNM;
	public static Location mCurrentLocation = null;
	
	// save all the nodes results of the alarm search
	private ArrayList<GeoNode> mNodeList = new ArrayList<GeoNode>();
	
	// save all the alarms
	private static ArrayList<GenericAlarm> mAlarmList = new ArrayList<GenericAlarm>();
	
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
	
	
    @Override
    public void onCreate() {
	   
    	
    	loadAlarms ();
    	
	   // Get Notification Service
       mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);        
       
       LocationService.registerLocationListener ( new ILocationServiceListener () {
			
			public void updateCurrentLocation(Location loc) {  
				Log.e("AlarmService:","Executting listener method");
				mCurrentLocation = loc;
                executeAllAlarms();
			}

		});

	   
    }
    
    @Override
    public void onDestroy() {
       // Cancel the persistent notification.
 	   mNM.cancel(1);
 	   
    }
    
    private static void saveAlarms ()
    {
    
    	File dirHandler = new File(FILE_ALARMS); 
		
		if (dirHandler.exists())
			dirHandler.delete();
		
    	FileOutputStream fileOut = null;
    	ObjectOutputStream objFD = null;
		try {
			fileOut = new FileOutputStream(FILE_ALARMS);
			objFD =new ObjectOutputStream(fileOut);
			
			objFD.writeObject(mAlarmList);
			
			objFD.close();
			
		} catch (FileNotFoundException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
		} catch (IOException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
		}
		
		Log.e("AlarmService: ", String.valueOf(mAlarmList.size()) + " alarms saved!");
    	
    }
    
	private static void loadAlarms ()
    {
    			
    	FileInputStream fileIn;
		try {
			fileIn = new FileInputStream(FILE_ALARMS);
			
			ObjectInputStream objFD = new ObjectInputStream(fileIn);
			
			mAlarmList= (ArrayList<GenericAlarm>) objFD.readObject();
			
			fileIn.close();
			
		} catch (FileNotFoundException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
			
		} catch (StreamCorruptedException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
			
		} catch (IOException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
			
		} catch (ClassNotFoundException e) {
			Log.e("AlarmService::Exception = ", e.getMessage());
		}
    	
		Log.e("AlarmService: ", String.valueOf(mAlarmList.size()) + " alarms loaded!");
    }
    
	public static ArrayList<GenericAlarm> getAlarms ()
	{
		return mAlarmList;
	}
	
    public static Integer registerAlarm (GenericAlarm ga)
    {
    	mAlarmList.add(ga);
    	
    	saveAlarms();
    	
    	return mAlarmList.size();
    }
    
    public static void unregisterAlarm (Integer pos)
    {
    	mAlarmList.remove(pos-1);
    	
    	saveAlarms();
    }
    
	private void showNotification ()
	{
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = "You have some places alarms (" + String.valueOf(mNodeList.size()) + ")";

        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.ruta_negro_48, text,
                System.currentTimeMillis());

        // The PendingIntent to launch our activity if the user selects this notification
        Intent IntentLGS = new Intent(this, new NodeList().getClass() );
        NodeListLayer layer1 = new NodeListLayer("AlarmNodes",null,null);
        layer1.setNodes(mNodeList);
		IntentLGS.putExtra ("layer",layer1);
		
		
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, IntentLGS, 0);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, "Alarm Notification", text, contentIntent);

        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        mNM.notify(1, notification);
        
		
	}
	
	private void executeAllAlarms()
	{
		mNodeList.clear();
		
		
		// Execute all the Alarms
		for (int i=0; i<mAlarmList.size(); i++)
		{
			 ArrayList <GeoNode> auxArray = mAlarmList.get(i).refreshData(mCurrentLocation);
			 
			 if (auxArray != null)
				 mNodeList.addAll(auxArray);
			 
		}

		
		// if there are some results, notify them in Bar Notification 
		if (mNodeList.size()>0)
			showNotification();
	}

}
